package cn.edu.hitwh.kanlema.listener;

import cn.edu.hitwh.kanlema.constant.MqConstants;
import cn.edu.hitwh.kanlema.constant.RedisConstants;
import cn.edu.hitwh.kanlema.constant.SystemConstants;
import cn.edu.hitwh.kanlema.entity.Follow;
import cn.edu.hitwh.kanlema.message.FeedMessage;
import cn.edu.hitwh.kanlema.service.IFollowService;
import cn.edu.hitwh.kanlema.util.SignUtil;
import cn.hutool.core.lang.Snowflake;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class BlogListener {
    @Autowired
    private IFollowService followService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private SignUtil signUtil;


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(MqConstants.BLOG_FEED_QUEUE),
            exchange = @Exchange(MqConstants.BLOG_EXCHANGE),
            key = MqConstants.BLOG_SEND_KEY
    ))
    public void listenFeedMessage(FeedMessage message) {
        Long blogId = message.getBlogId();
        Long userId = message.getUserId();

        // 获取用户活跃度，计算用户收件箱容量
        LocalDate now = LocalDate.now();
        LocalDate since = now.minusDays(SystemConstants.MAX_ACTIVE_DAYS);
        long activeDays = signUtil.getSignCount(userId, since, now);
        long capacity = activeDays * RedisConstants.BLOG_FEED_CAPACITY;

        // 获取粉丝列表
        List<Long> fanIds = followService.lambdaQuery()
                .eq(Follow::getFollowUserId, userId)
                .select(Follow::getUserId)
                .list()
                .stream()
                .map(Follow::getUserId)
                .collect(Collectors.toList());
        for (Long fanId : fanIds) {
            String feedKey = RedisConstants.BLOG_FEED_KEY + fanId;
            redisTemplate.opsForZSet()
                    .add(feedKey, blogId.toString(), blogId);
            // 检查是否超过容量
            Long size = redisTemplate.opsForZSet().size(feedKey);
            if (size != null && size > capacity) {
                RLock lock = redissonClient.getLock(RedisConstants.BLOG_FEED_LOCK_KEY + userId);
                if (!lock.tryLock()) {
                    continue;
                }
                try {
                    size = redisTemplate.opsForZSet().size(feedKey);
                    if (size != null && size > capacity) {
                        redisTemplate.opsForZSet()
                                .removeRange(feedKey, size - capacity, size - 1);
                    }
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}
